package net.lovesrc.support.service.mobileverifycode;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.zhouzhou.fastjava.BizException;
import com.zhouzhou.fastjava.util.ThreadKit;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class AbstractMobileVerifyCodeService implements MobileVerifyCodeService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    private Cache<String, String> tokenCache = CacheBuilder
            .newBuilder()
            .expireAfterAccess(2, TimeUnit.HOURS)
            .expireAfterWrite(24, TimeUnit.HOURS)
            .maximumSize(1024)
            .build();


    protected String getToken() {
        String token = tokenCache.getIfPresent("token");
        if (StringUtils.isBlank(token)) {
            token = login();
            tokenCache.put("token", token);
        }
        return token;
    }

    @Override
    public String getPhone(String itemId) {
        return this.getPhone(itemId, null);
    }

    @Override
    public String getPhone(String itemId, String phone) {
        return getPhone(itemId,phone,"0");
    }

    @Override
    public String getVerifyCodeFromPhone(String itemId, String phone) {
        return this.getVerifyCodeFromPhone(itemId, phone, 6);
    }

    @Override
    public final String getVerifyCodeFromPhone(String itemId, String phone, int size) {
        for (int i = 0; i < 40; i++) {
            String message = doGetVerifyCodeFromPhone(itemId, phone);
            if (StringUtils.isNotBlank(message)) {
                Matcher matcher = Pattern.compile("\\d{" + size + "}").matcher(message);
                if (matcher.find()) {
                    releasePhone(itemId, phone);
                    return matcher.group();
                } else {
                    ThreadKit.sleepSeconds(5);
                }
            } else {
                ThreadKit.sleepSeconds(5);
            }
        }
        releasePhone(itemId, phone);
        throw BizException.messageOf("未能获取到验证码");
    }

    protected abstract String doGetVerifyCodeFromPhone(String itemId, String phone);

    protected abstract String login();

}
